Load Data


library(readxl)
library(tidyr)
library(dplyr)
library(ggplot2)
library(plotly)

source("../../Accelerate/notebooks/custom_functions.R")

teams = read_excel("../data/O17ClimateGender_teamformation.xlsx")
#teams = lapply(teams, as.character)

assesment = read_excel("../data/O17ClimateGender_assessment.xlsx")

load("../../Accelerate/processed data/registration.RData")

map = read.csv("../../Accelerate/data/team_users_hashed.csv", stringsAsFactors = FALSE)
colnames(map) = c("Team", "ID", "Hash", "Mentors")

reg = merge(reg, map[,c("Team", "Hash")], by.x = "ID", by.y = "Hash")

reg_map = c("A2: Women & Technology Against Climate Change" = "T6: Women & Technology Against Climate Change", "B2: TEAM FOILED" = "T3: TEAM FOILED", "C1: Andapé Institute" = "T13: Andapé Institute", "C3: WOMER" = "T5: WOMER", "A5: Donate Water Project" = "T9: DonateWater", "B5: Rights of Climate" = "T11: Rights of Climate", "B3: Eco Winners" = "T14: Eco Winners", "B4: Women 4 Sustainable World" = "T12: Women 4 Sustainable World", "A1: Up Get App/CitiCERN" = "T7: UpGet app - CitiCERN Project", "B1: Water Warriors" = "T10: Water Warriors", "C2: PAM" = "T4: PAM", "C4: Climate Gender Justice" = "T8: Climate Gender Justice", "A3: Rhythm of Bamboos" = "T1: SDesiGn (Old name: Rhythm of Bamboos)", "C5: Ashifa Nazrin" = "C5: Ashifa Nazrin", "A4: Flood Rangers" = "T2: Flood Rangers")

reg_map = data.frame(old_name = names(reg_map), new_name = reg_map)
reg = merge(reg, reg_map, by.x = "Team", by.y = "old_name", all.x = TRUE)

write.csv(unnest(reg, cols = c("communication")), file = "../processed data/reg_edited.csv")

map = merge(map, reg_map, by.x = "Team", by.y = "old_name", all.x = TRUE)
map$new_name = as.character(map$new_name)
map$new_name[map$Team == "Organizing Team"] = "Organizing Team"

Outcome Variable


outcome = assesment[,c("Team", "Total", "Weekly Evaluation", "Commitment", "Attendance", "Deliverables")]
outcome = merge(outcome, teams[,c("Team Name", "Stage")], by.x = "Team", by.y = "Team Name", all.x = TRUE)
outcome$Stage = factor(outcome$Stage, levels = c("Evaluate", "Accelerate", "Refine"), ordered = TRUE)

Surveys and Interactions


load("../../Evaluate/processed data/surveys.RData")

inter = interactions[,c(1,8,2,3)]
inter = merge(inter, map[,c("ID", "new_name")], by.x = "user_id", by.y = "ID", all.x = TRUE)
colnames(inter) = c("From", "To", "Survey_id", "Question", "From_team")
inter = merge(inter, map[,c("ID", "new_name")], by.x = "To", by.y = "ID", all.x = TRUE)
colnames(inter)[colnames(inter) == "new_name"] = "To_team"

inter = inter[!inter$To %in% c(34), c(2,1,3,4,5,6)]

g_int_teams = graph_from_data_frame(inter[,c(5,6,1:4)], directed = FALSE, vertices = teams)
E(g_int_teams)$weight = 1
g_int_teams_simp = simplify(g_int_teams, remove.loops = FALSE)

Data Frame of properties - Surveys


stats = data.frame()

for (i in V(g_int_teams_simp)$name)
{
  if (!i %in% "Organizing Team")
  {
    intra = E(g_int_teams_simp)$weight[get.edge.ids(g_int_teams_simp, vp = c(i, i))]
    org = E(g_int_teams_simp)$weight[get.edge.ids(g_int_teams_simp, vp = c(i, "Organizing Team"))]
    total = strength(g_int_teams_simp, vids = i)
    
    stats = rbind(stats, data.frame(Team = i, strength_intra_team = intra, strength_org_team = org, strength_inter_team = (total - (2*intra) - org), strength_intra_team_norm = 2*intra/total, strength_org_team_norm = org/total, strength_inter_team_norm = (total - (2*intra) - org)/total))
  }
}

Data Frame of Properties - Slack


load("../../Evaluate/processed data/slack_all_int.RData")
g_slack = graph_from_data_frame(df_total[,c(3,4,1,2,3)], directed = FALSE)
E(g_slack)$weight = 1
g_slack_simp = simplify(g_slack, remove.loops = FALSE)

stats_slack = data.frame()

for (i in V(g_slack_simp)$name)
{
  if (!i %in% c("Organizing Team", "Tool Owner"))
  {
    intra = E(g_slack_simp)$weight[get.edge.ids(g_slack_simp, vp = c(i, i))]
    org = E(g_slack_simp)$weight[get.edge.ids(g_slack_simp, vp = c(i, "Organizing Team"))]
    total = strength(g_slack_simp, vids = i)
    
    if (length(intra) == 0)
      intra = 0
    if (length(org) == 0)
      org = 0
    
    stats_slack = rbind(stats_slack, data.frame(Team = i, slack_strength_intra_team = intra, slack_strength_org_team = org, slack_strength_inter_team = (total - (2*intra) - org), slack_strength_intra_team_norm = 2*intra/total, slack_strength_org_team_norm = org/total, slack_strength_inter_team_norm = (total - (2*intra) - org)/total))
  }
}

Merge Interaction Properties


stats_slack = merge(stats_slack, reg_map, by.x = "Team", by.y = "old_name", all.x = TRUE)
stats_slack$Team = stats_slack$new_name
stats_slack = stats_slack %>% select(-new_name)

interaction_stats = merge(stats, stats_slack, by.x = "Team", by.y = "Team", all.x = TRUE, all.y = TRUE)

Clean Correlation Plot


temp = merge(interaction_stats, outcome, by.x = "Team", by.y = "Team", all.x = TRUE, all.y = TRUE)

df_corr = data.frame()

for (i in colnames(outcome))
{
  if(! i %in% c("Team", "Stage"))
  {
    for (j in colnames(interaction_stats))
    {
      if(!j %in% c("Team"))
      {
        c = cor.test(temp[,j], temp[,i])
        
        df_corr = rbind(df_corr, data.frame(i = i, j = j, cor = c$estimate, p_val = c$p.value))
        
      }
    }
  }
}

df_corr$cor[df_corr$p_val > 0.1] = 0
df_corr$cor = round(df_corr$cor, 3)

plt = ggplot(df_corr) + geom_tile(aes(x = i, y = j, fill = cor), lwd = 1.5, linetype = 1) + scale_fill_gradient2(low = "blue", high = "red") + theme_bw() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank()) + ylab("") + xlab("") + geom_text(aes(x = i, y = j, label = cor)) + ggtitle("Correlation Plot - Network Strength vs Outcome")

ggplotly(plt)
NA
NA

Diversity Measures


shannon = function(list)
{
  ent = 0
  for (i in unique(list))
  {
    t = sum(list == i)
    n = length(list)
    ent = ent + (t/n)*log(t/n)
  }
  
  return(-1*ent)
}

simpson = function(list)
{
  ent = 0
  for (i in unique(list))
  {
    t = sum(list == i)
    n = length(list)
    ent = ent + (t/n)*(t/n)
  }
  
  return(1/ent)
}

metrics = data.frame(Team = unique(reg$new_name))

for (i in c("gender", "country_orig", "country_resid", "education", "communication", "exante_project_SDG", "background", "occupation"))
{
  temp = reg[,c("new_name", i)]
  temp = clean_split_mcq(temp)
  colnames(temp) = c("Team", "var")
  

  t = temp %>% group_by(Team) %>% summarise(shannon = shannon(var), simpson = simpson(var), span = length(unique(var)))
  colnames(t) = c("Team", paste(i, "_shannon", sep = ''), paste(i, "_simpson", sep = ''), paste(i, "_span", sep = ''))
  
  metrics = merge(metrics, t, by.x = "Team", by.y = "Team", all.x = TRUE, all.y = TRUE)
  
}

metrics = merge(metrics, teams, by.x = "Team", by.y = "Team Name", all.x = TRUE)


temp = merge(metrics[,c(1:25)], outcome, by.x = "Team", by.y = "Team")

df_corr = data.frame()

for (i in colnames(outcome))
{
  if(! i %in% c("Team", "Stage"))
  {
    for (j in colnames(metrics))
    {
      if(!j %in% c("Team", "Type", "Stage"))
      {
        c = cor.test(temp[,j], temp[,i])
        
        df_corr = rbind(df_corr, data.frame(i = i, j = j, cor = c$estimate, p_val = c$p.value))
        
      }
    }
  }
}

df_corr$cor[df_corr$p_val > 0.1] = 0
df_corr$cor = round(df_corr$cor, 3)

plt = ggplot(df_corr) + geom_tile(aes(x = i, y = j, fill = cor), lwd = 1.5, linetype = 1) + scale_fill_gradient2(low = "blue", high = "red") + theme_bw() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank()) + ylab("") + xlab("") + geom_text(aes(x = i, y = j, label = cor)) + ggtitle("Correlation Plot - Diversity Measures vs Outcome")

ggplotly(plt)
NA

Slack Correlations (Special Questions)


pdf("../figures/interaction_questions_outcome_correlation.pdf")

for(k in unique(inter$Question))
{
  g_temp = graph_from_data_frame(inter[inter$Question == k, c(5,6,1:4)], directed = FALSE, vertices = teams)
  E(g_temp)$weight = 1
  g_temp_simp = simplify(g_temp, remove.loops = FALSE)
  
  stats = data.frame()

  for (i in V(g_temp_simp)$name)
  {
    if (!i %in% "Organizing Team")
    {
      intra = E(g_temp_simp)$weight[get.edge.ids(g_temp_simp, vp = c(i, i))]
      org = E(g_temp_simp)$weight[get.edge.ids(g_temp_simp, vp = c(i, "Organizing Team"))]
      total = strength(g_temp_simp, vids = i)
      
      if (length(intra) == 0) 
        intra = 0
      if(length(org) == 0)
        org = 0
    
      stats = rbind(stats, data.frame(Team = i, strength_intra_team = intra, strength_org_team = org, strength_inter_team = (total - (2*intra) - org), strength_intra_team_norm = 2*intra/total, strength_org_team_norm = org/total, strength_inter_team_norm = (total - (2*intra) - org)/total))
    }
  }
  
  temp = merge(stats, outcome, by.x = "Team", by.y = "Team", all.x = TRUE, all.y = TRUE)

  df_corr = data.frame()
  
  for (i in colnames(outcome))
  {
    if(! i %in% c("Team", "Stage"))
    {
      for (j in colnames(stats))
      {
        if(!j %in% c("Team"))
        {
          c = cor.test(temp[,j], temp[,i])
          
          df_corr = rbind(df_corr, data.frame(i = i, j = j, cor = c$estimate, p_val = c$p.value))
          
        }
      }
    }
  }
  
  df_corr$cor[df_corr$p_val > 0.1] = 0
  df_corr$cor = round(df_corr$cor, 3)
  
  plt = ggplot(df_corr) + geom_tile(aes(x = i, y = j, fill = cor), lwd = 1.5, linetype = 1) + scale_fill_gradient2(low = "blue", high = "red") + theme_bw() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank()) + ylab("") + xlab("") + geom_text(aes(x = i, y = j, label = cor)) + ggtitle(k)
  
  print(plt)
}
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning in cor(x, y) : the standard deviation is zero
Warning: Removed 10 rows containing missing values (geom_text).
dev.off()
null device 
          1 

Stages Crossed vs Properties (Evaluate)


interaction_stats = merge(interaction_stats, teams, by.x = "Team", by.y = "Team Name", all.x = TRUE)

pdf("../figures/stage_props.pdf")

for (i in colnames(interaction_stats))
{
  if (! i %in% c("Team", "Stage", 'Type'))
  {
    temp = interaction_stats[, c("Stage", i)]
    colnames(temp) = c("Stage", "var")
    
    plt = ggplot(temp, aes(x = Stage, y = var)) + geom_point(aes(x = Stage, y = var), alpha = 0.3) + theme_bw(base_size = 25) + geom_boxplot() + ggtitle(i) + ylab("")
    print(plt)
  }
}

dev.off()
null device 
          1 
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCkxvYWQgRGF0YQoKYGBge3J9CgpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeSh0aWR5cikKbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBsb3RseSkKCnNvdXJjZSgiLi4vLi4vQWNjZWxlcmF0ZS9ub3RlYm9va3MvY3VzdG9tX2Z1bmN0aW9ucy5SIikKCnRlYW1zID0gcmVhZF9leGNlbCgiLi4vZGF0YS9PMTdDbGltYXRlR2VuZGVyX3RlYW1mb3JtYXRpb24ueGxzeCIpCiN0ZWFtcyA9IGxhcHBseSh0ZWFtcywgYXMuY2hhcmFjdGVyKQoKYXNzZXNtZW50ID0gcmVhZF9leGNlbCgiLi4vZGF0YS9PMTdDbGltYXRlR2VuZGVyX2Fzc2Vzc21lbnQueGxzeCIpCgpsb2FkKCIuLi8uLi9BY2NlbGVyYXRlL3Byb2Nlc3NlZCBkYXRhL3JlZ2lzdHJhdGlvbi5SRGF0YSIpCgptYXAgPSByZWFkLmNzdigiLi4vLi4vQWNjZWxlcmF0ZS9kYXRhL3RlYW1fdXNlcnNfaGFzaGVkLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKY29sbmFtZXMobWFwKSA9IGMoIlRlYW0iLCAiSUQiLCAiSGFzaCIsICJNZW50b3JzIikKCnJlZyA9IG1lcmdlKHJlZywgbWFwWyxjKCJUZWFtIiwgIkhhc2giKV0sIGJ5LnggPSAiSUQiLCBieS55ID0gIkhhc2giKQoKcmVnX21hcCA9IGMoIkEyOiBXb21lbiAmIFRlY2hub2xvZ3kgQWdhaW5zdCBDbGltYXRlIENoYW5nZSIgPSAiVDY6IFdvbWVuICYgVGVjaG5vbG9neSBBZ2FpbnN0IENsaW1hdGUgQ2hhbmdlIiwgIkIyOiBURUFNIEZPSUxFRCIgPSAiVDM6IFRFQU0gRk9JTEVEIiwgIkMxOiBBbmRhcMOpIEluc3RpdHV0ZSIgPSAiVDEzOiBBbmRhcMOpIEluc3RpdHV0ZSIsICJDMzogV09NRVIiID0gIlQ1OiBXT01FUiIsICJBNTogRG9uYXRlIFdhdGVyIFByb2plY3QiID0gIlQ5OiBEb25hdGVXYXRlciIsICJCNTogUmlnaHRzIG9mIENsaW1hdGUiID0gIlQxMTogUmlnaHRzIG9mIENsaW1hdGUiLCAiQjM6IEVjbyBXaW5uZXJzIiA9ICJUMTQ6IEVjbyBXaW5uZXJzIiwgIkI0OiBXb21lbiA0IFN1c3RhaW5hYmxlIFdvcmxkIiA9ICJUMTI6IFdvbWVuIDQgU3VzdGFpbmFibGUgV29ybGQiLCAiQTE6IFVwIEdldCBBcHAvQ2l0aUNFUk4iID0gIlQ3OiBVcEdldCBhcHAgLSBDaXRpQ0VSTiBQcm9qZWN0IiwgIkIxOiBXYXRlciBXYXJyaW9ycyIgPSAiVDEwOiBXYXRlciBXYXJyaW9ycyIsICJDMjogUEFNIiA9ICJUNDogUEFNIiwgIkM0OiBDbGltYXRlIEdlbmRlciBKdXN0aWNlIiA9ICJUODogQ2xpbWF0ZSBHZW5kZXIgSnVzdGljZSIsICJBMzogUmh5dGhtIG9mIEJhbWJvb3MiID0gIlQxOiBTRGVzaUduIChPbGQgbmFtZTogUmh5dGhtIG9mIEJhbWJvb3MpIiwgIkM1OiBBc2hpZmEgTmF6cmluIiA9ICJDNTogQXNoaWZhIE5henJpbiIsICJBNDogRmxvb2QgUmFuZ2VycyIgPSAiVDI6IEZsb29kIFJhbmdlcnMiKQoKcmVnX21hcCA9IGRhdGEuZnJhbWUob2xkX25hbWUgPSBuYW1lcyhyZWdfbWFwKSwgbmV3X25hbWUgPSByZWdfbWFwKQpyZWcgPSBtZXJnZShyZWcsIHJlZ19tYXAsIGJ5LnggPSAiVGVhbSIsIGJ5LnkgPSAib2xkX25hbWUiLCBhbGwueCA9IFRSVUUpCgp3cml0ZS5jc3YodW5uZXN0KHJlZywgY29scyA9IGMoImNvbW11bmljYXRpb24iKSksIGZpbGUgPSAiLi4vcHJvY2Vzc2VkIGRhdGEvcmVnX2VkaXRlZC5jc3YiKQoKbWFwID0gbWVyZ2UobWFwLCByZWdfbWFwLCBieS54ID0gIlRlYW0iLCBieS55ID0gIm9sZF9uYW1lIiwgYWxsLnggPSBUUlVFKQptYXAkbmV3X25hbWUgPSBhcy5jaGFyYWN0ZXIobWFwJG5ld19uYW1lKQptYXAkbmV3X25hbWVbbWFwJFRlYW0gPT0gIk9yZ2FuaXppbmcgVGVhbSJdID0gIk9yZ2FuaXppbmcgVGVhbSIKCgpgYGAKCk91dGNvbWUgVmFyaWFibGUKCgpgYGB7cn0KCm91dGNvbWUgPSBhc3Nlc21lbnRbLGMoIlRlYW0iLCAiVG90YWwiLCAiV2Vla2x5IEV2YWx1YXRpb24iLCAiQ29tbWl0bWVudCIsICJBdHRlbmRhbmNlIiwgIkRlbGl2ZXJhYmxlcyIpXQpvdXRjb21lID0gbWVyZ2Uob3V0Y29tZSwgdGVhbXNbLGMoIlRlYW0gTmFtZSIsICJTdGFnZSIpXSwgYnkueCA9ICJUZWFtIiwgYnkueSA9ICJUZWFtIE5hbWUiLCBhbGwueCA9IFRSVUUpCm91dGNvbWUkU3RhZ2UgPSBmYWN0b3Iob3V0Y29tZSRTdGFnZSwgbGV2ZWxzID0gYygiRXZhbHVhdGUiLCAiQWNjZWxlcmF0ZSIsICJSZWZpbmUiKSwgb3JkZXJlZCA9IFRSVUUpCgpgYGAKCgpTdXJ2ZXlzIGFuZCBJbnRlcmFjdGlvbnMKCmBgYHtyfQoKbG9hZCgiLi4vLi4vRXZhbHVhdGUvcHJvY2Vzc2VkIGRhdGEvc3VydmV5cy5SRGF0YSIpCgppbnRlciA9IGludGVyYWN0aW9uc1ssYygxLDgsMiwzKV0KaW50ZXIgPSBtZXJnZShpbnRlciwgbWFwWyxjKCJJRCIsICJuZXdfbmFtZSIpXSwgYnkueCA9ICJ1c2VyX2lkIiwgYnkueSA9ICJJRCIsIGFsbC54ID0gVFJVRSkKY29sbmFtZXMoaW50ZXIpID0gYygiRnJvbSIsICJUbyIsICJTdXJ2ZXlfaWQiLCAiUXVlc3Rpb24iLCAiRnJvbV90ZWFtIikKaW50ZXIgPSBtZXJnZShpbnRlciwgbWFwWyxjKCJJRCIsICJuZXdfbmFtZSIpXSwgYnkueCA9ICJUbyIsIGJ5LnkgPSAiSUQiLCBhbGwueCA9IFRSVUUpCmNvbG5hbWVzKGludGVyKVtjb2xuYW1lcyhpbnRlcikgPT0gIm5ld19uYW1lIl0gPSAiVG9fdGVhbSIKCmludGVyID0gaW50ZXJbIWludGVyJFRvICVpbiUgYygzNCksIGMoMiwxLDMsNCw1LDYpXQoKZ19pbnRfdGVhbXMgPSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoaW50ZXJbLGMoNSw2LDE6NCldLCBkaXJlY3RlZCA9IEZBTFNFLCB2ZXJ0aWNlcyA9IHRlYW1zKQpFKGdfaW50X3RlYW1zKSR3ZWlnaHQgPSAxCmdfaW50X3RlYW1zX3NpbXAgPSBzaW1wbGlmeShnX2ludF90ZWFtcywgcmVtb3ZlLmxvb3BzID0gRkFMU0UpCgpgYGAKCkRhdGEgRnJhbWUgb2YgcHJvcGVydGllcyAtIFN1cnZleXMKCgpgYGB7cn0KCnN0YXRzID0gZGF0YS5mcmFtZSgpCgpmb3IgKGkgaW4gVihnX2ludF90ZWFtc19zaW1wKSRuYW1lKQp7CiAgaWYgKCFpICVpbiUgIk9yZ2FuaXppbmcgVGVhbSIpCiAgewogICAgaW50cmEgPSBFKGdfaW50X3RlYW1zX3NpbXApJHdlaWdodFtnZXQuZWRnZS5pZHMoZ19pbnRfdGVhbXNfc2ltcCwgdnAgPSBjKGksIGkpKV0KICAgIG9yZyA9IEUoZ19pbnRfdGVhbXNfc2ltcCkkd2VpZ2h0W2dldC5lZGdlLmlkcyhnX2ludF90ZWFtc19zaW1wLCB2cCA9IGMoaSwgIk9yZ2FuaXppbmcgVGVhbSIpKV0KICAgIHRvdGFsID0gc3RyZW5ndGgoZ19pbnRfdGVhbXNfc2ltcCwgdmlkcyA9IGkpCiAgICAKICAgIHN0YXRzID0gcmJpbmQoc3RhdHMsIGRhdGEuZnJhbWUoVGVhbSA9IGksIHN0cmVuZ3RoX2ludHJhX3RlYW0gPSBpbnRyYSwgc3RyZW5ndGhfb3JnX3RlYW0gPSBvcmcsIHN0cmVuZ3RoX2ludGVyX3RlYW0gPSAodG90YWwgLSAoMippbnRyYSkgLSBvcmcpLCBzdHJlbmd0aF9pbnRyYV90ZWFtX25vcm0gPSAyKmludHJhL3RvdGFsLCBzdHJlbmd0aF9vcmdfdGVhbV9ub3JtID0gb3JnL3RvdGFsLCBzdHJlbmd0aF9pbnRlcl90ZWFtX25vcm0gPSAodG90YWwgLSAoMippbnRyYSkgLSBvcmcpL3RvdGFsKSkKICB9Cn0KCmBgYAoKRGF0YSBGcmFtZSBvZiBQcm9wZXJ0aWVzIC0gU2xhY2sKCmBgYHtyfQoKbG9hZCgiLi4vLi4vRXZhbHVhdGUvcHJvY2Vzc2VkIGRhdGEvc2xhY2tfYWxsX2ludC5SRGF0YSIpCmdfc2xhY2sgPSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoZGZfdG90YWxbLGMoMyw0LDEsMiwzKV0sIGRpcmVjdGVkID0gRkFMU0UpCkUoZ19zbGFjaykkd2VpZ2h0ID0gMQpnX3NsYWNrX3NpbXAgPSBzaW1wbGlmeShnX3NsYWNrLCByZW1vdmUubG9vcHMgPSBGQUxTRSkKCnN0YXRzX3NsYWNrID0gZGF0YS5mcmFtZSgpCgpmb3IgKGkgaW4gVihnX3NsYWNrX3NpbXApJG5hbWUpCnsKICBpZiAoIWkgJWluJSBjKCJPcmdhbml6aW5nIFRlYW0iLCAiVG9vbCBPd25lciIpKQogIHsKICAgIGludHJhID0gRShnX3NsYWNrX3NpbXApJHdlaWdodFtnZXQuZWRnZS5pZHMoZ19zbGFja19zaW1wLCB2cCA9IGMoaSwgaSkpXQogICAgb3JnID0gRShnX3NsYWNrX3NpbXApJHdlaWdodFtnZXQuZWRnZS5pZHMoZ19zbGFja19zaW1wLCB2cCA9IGMoaSwgIk9yZ2FuaXppbmcgVGVhbSIpKV0KICAgIHRvdGFsID0gc3RyZW5ndGgoZ19zbGFja19zaW1wLCB2aWRzID0gaSkKICAgIAogICAgaWYgKGxlbmd0aChpbnRyYSkgPT0gMCkKICAgICAgaW50cmEgPSAwCiAgICBpZiAobGVuZ3RoKG9yZykgPT0gMCkKICAgICAgb3JnID0gMAogICAgCiAgICBzdGF0c19zbGFjayA9IHJiaW5kKHN0YXRzX3NsYWNrLCBkYXRhLmZyYW1lKFRlYW0gPSBpLCBzbGFja19zdHJlbmd0aF9pbnRyYV90ZWFtID0gaW50cmEsIHNsYWNrX3N0cmVuZ3RoX29yZ190ZWFtID0gb3JnLCBzbGFja19zdHJlbmd0aF9pbnRlcl90ZWFtID0gKHRvdGFsIC0gKDIqaW50cmEpIC0gb3JnKSwgc2xhY2tfc3RyZW5ndGhfaW50cmFfdGVhbV9ub3JtID0gMippbnRyYS90b3RhbCwgc2xhY2tfc3RyZW5ndGhfb3JnX3RlYW1fbm9ybSA9IG9yZy90b3RhbCwgc2xhY2tfc3RyZW5ndGhfaW50ZXJfdGVhbV9ub3JtID0gKHRvdGFsIC0gKDIqaW50cmEpIC0gb3JnKS90b3RhbCkpCiAgfQp9CgpgYGAKCk1lcmdlIEludGVyYWN0aW9uIFByb3BlcnRpZXMKCmBgYHtyfQoKc3RhdHNfc2xhY2sgPSBtZXJnZShzdGF0c19zbGFjaywgcmVnX21hcCwgYnkueCA9ICJUZWFtIiwgYnkueSA9ICJvbGRfbmFtZSIsIGFsbC54ID0gVFJVRSkKc3RhdHNfc2xhY2skVGVhbSA9IHN0YXRzX3NsYWNrJG5ld19uYW1lCnN0YXRzX3NsYWNrID0gc3RhdHNfc2xhY2sgJT4lIHNlbGVjdCgtbmV3X25hbWUpCgppbnRlcmFjdGlvbl9zdGF0cyA9IG1lcmdlKHN0YXRzLCBzdGF0c19zbGFjaywgYnkueCA9ICJUZWFtIiwgYnkueSA9ICJUZWFtIiwgYWxsLnggPSBUUlVFLCBhbGwueSA9IFRSVUUpCgpgYGAKCkNsZWFuIENvcnJlbGF0aW9uIFBsb3QKCmBgYHtyfQoKdGVtcCA9IG1lcmdlKGludGVyYWN0aW9uX3N0YXRzLCBvdXRjb21lLCBieS54ID0gIlRlYW0iLCBieS55ID0gIlRlYW0iLCBhbGwueCA9IFRSVUUsIGFsbC55ID0gVFJVRSkKCmRmX2NvcnIgPSBkYXRhLmZyYW1lKCkKCmZvciAoaSBpbiBjb2xuYW1lcyhvdXRjb21lKSkKewogIGlmKCEgaSAlaW4lIGMoIlRlYW0iLCAiU3RhZ2UiKSkKICB7CiAgICBmb3IgKGogaW4gY29sbmFtZXMoaW50ZXJhY3Rpb25fc3RhdHMpKQogICAgewogICAgICBpZighaiAlaW4lIGMoIlRlYW0iKSkKICAgICAgewogICAgICAgIGMgPSBjb3IudGVzdCh0ZW1wWyxqXSwgdGVtcFssaV0pCiAgICAgICAgCiAgICAgICAgZGZfY29yciA9IHJiaW5kKGRmX2NvcnIsIGRhdGEuZnJhbWUoaSA9IGksIGogPSBqLCBjb3IgPSBjJGVzdGltYXRlLCBwX3ZhbCA9IGMkcC52YWx1ZSkpCiAgICAgICAgCiAgICAgIH0KICAgIH0KICB9Cn0KCmRmX2NvcnIkY29yW2RmX2NvcnIkcF92YWwgPiAwLjFdID0gMApkZl9jb3JyJGNvciA9IHJvdW5kKGRmX2NvcnIkY29yLCAzKQoKcGx0ID0gZ2dwbG90KGRmX2NvcnIpICsgZ2VvbV90aWxlKGFlcyh4ID0gaSwgeSA9IGosIGZpbGwgPSBjb3IpLCBsd2QgPSAxLjUsIGxpbmV0eXBlID0gMSkgKyBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsIGhpZ2ggPSAicmVkIikgKyB0aGVtZV9idygpICsgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkgKyB5bGFiKCIiKSArIHhsYWIoIiIpICsgZ2VvbV90ZXh0KGFlcyh4ID0gaSwgeSA9IGosIGxhYmVsID0gY29yKSkgKyBnZ3RpdGxlKCJDb3JyZWxhdGlvbiBQbG90IC0gTmV0d29yayBTdHJlbmd0aCB2cyBPdXRjb21lIikKCmdncGxvdGx5KHBsdCkKCgpgYGAKCkRpdmVyc2l0eSBNZWFzdXJlcwoKYGBge3J9CgpzaGFubm9uID0gZnVuY3Rpb24obGlzdCkKewogIGVudCA9IDAKICBmb3IgKGkgaW4gdW5pcXVlKGxpc3QpKQogIHsKICAgIHQgPSBzdW0obGlzdCA9PSBpKQogICAgbiA9IGxlbmd0aChsaXN0KQogICAgZW50ID0gZW50ICsgKHQvbikqbG9nKHQvbikKICB9CiAgCiAgcmV0dXJuKC0xKmVudCkKfQoKc2ltcHNvbiA9IGZ1bmN0aW9uKGxpc3QpCnsKICBlbnQgPSAwCiAgZm9yIChpIGluIHVuaXF1ZShsaXN0KSkKICB7CiAgICB0ID0gc3VtKGxpc3QgPT0gaSkKICAgIG4gPSBsZW5ndGgobGlzdCkKICAgIGVudCA9IGVudCArICh0L24pKih0L24pCiAgfQogIAogIHJldHVybigxL2VudCkKfQoKYGBgCgpgYGB7cn0KCm1ldHJpY3MgPSBkYXRhLmZyYW1lKFRlYW0gPSB1bmlxdWUocmVnJG5ld19uYW1lKSkKCmZvciAoaSBpbiBjKCJnZW5kZXIiLCAiY291bnRyeV9vcmlnIiwgImNvdW50cnlfcmVzaWQiLCAiZWR1Y2F0aW9uIiwgImNvbW11bmljYXRpb24iLCAiZXhhbnRlX3Byb2plY3RfU0RHIiwgImJhY2tncm91bmQiLCAib2NjdXBhdGlvbiIpKQp7CiAgdGVtcCA9IHJlZ1ssYygibmV3X25hbWUiLCBpKV0KICB0ZW1wID0gY2xlYW5fc3BsaXRfbWNxKHRlbXApCiAgY29sbmFtZXModGVtcCkgPSBjKCJUZWFtIiwgInZhciIpCiAgCgogIHQgPSB0ZW1wICU+JSBncm91cF9ieShUZWFtKSAlPiUgc3VtbWFyaXNlKHNoYW5ub24gPSBzaGFubm9uKHZhciksIHNpbXBzb24gPSBzaW1wc29uKHZhciksIHNwYW4gPSBsZW5ndGgodW5pcXVlKHZhcikpKQogIGNvbG5hbWVzKHQpID0gYygiVGVhbSIsIHBhc3RlKGksICJfc2hhbm5vbiIsIHNlcCA9ICcnKSwgcGFzdGUoaSwgIl9zaW1wc29uIiwgc2VwID0gJycpLCBwYXN0ZShpLCAiX3NwYW4iLCBzZXAgPSAnJykpCiAgCiAgbWV0cmljcyA9IG1lcmdlKG1ldHJpY3MsIHQsIGJ5LnggPSAiVGVhbSIsIGJ5LnkgPSAiVGVhbSIsIGFsbC54ID0gVFJVRSwgYWxsLnkgPSBUUlVFKQogIAp9CgptZXRyaWNzID0gbWVyZ2UobWV0cmljcywgdGVhbXMsIGJ5LnggPSAiVGVhbSIsIGJ5LnkgPSAiVGVhbSBOYW1lIiwgYWxsLnggPSBUUlVFKQoKYGBgCgpgYGB7cn0KCgp0ZW1wID0gbWVyZ2UobWV0cmljc1ssYygxOjI1KV0sIG91dGNvbWUsIGJ5LnggPSAiVGVhbSIsIGJ5LnkgPSAiVGVhbSIpCgpkZl9jb3JyID0gZGF0YS5mcmFtZSgpCgpmb3IgKGkgaW4gY29sbmFtZXMob3V0Y29tZSkpCnsKICBpZighIGkgJWluJSBjKCJUZWFtIiwgIlN0YWdlIikpCiAgewogICAgZm9yIChqIGluIGNvbG5hbWVzKG1ldHJpY3MpKQogICAgewogICAgICBpZighaiAlaW4lIGMoIlRlYW0iLCAiVHlwZSIsICJTdGFnZSIpKQogICAgICB7CiAgICAgICAgYyA9IGNvci50ZXN0KHRlbXBbLGpdLCB0ZW1wWyxpXSkKICAgICAgICAKICAgICAgICBkZl9jb3JyID0gcmJpbmQoZGZfY29yciwgZGF0YS5mcmFtZShpID0gaSwgaiA9IGosIGNvciA9IGMkZXN0aW1hdGUsIHBfdmFsID0gYyRwLnZhbHVlKSkKICAgICAgICAKICAgICAgfQogICAgfQogIH0KfQoKZGZfY29yciRjb3JbZGZfY29yciRwX3ZhbCA+IDAuMV0gPSAwCmRmX2NvcnIkY29yID0gcm91bmQoZGZfY29yciRjb3IsIDMpCgpwbHQgPSBnZ3Bsb3QoZGZfY29ycikgKyBnZW9tX3RpbGUoYWVzKHggPSBpLCB5ID0gaiwgZmlsbCA9IGNvciksIGx3ZCA9IDEuNSwgbGluZXR5cGUgPSAxKSArIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdyA9ICJibHVlIiwgaGlnaCA9ICJyZWQiKSArIHRoZW1lX2J3KCkgKyB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSArIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZW9tX3RleHQoYWVzKHggPSBpLCB5ID0gaiwgbGFiZWwgPSBjb3IpKSArIGdndGl0bGUoIkNvcnJlbGF0aW9uIFBsb3QgLSBEaXZlcnNpdHkgTWVhc3VyZXMgdnMgT3V0Y29tZSIpCgpnZ3Bsb3RseShwbHQpCgpgYGAKClNsYWNrIENvcnJlbGF0aW9ucyAoU3BlY2lhbCBRdWVzdGlvbnMpCgpgYGB7cn0KCnBkZigiLi4vZmlndXJlcy9pbnRlcmFjdGlvbl9xdWVzdGlvbnNfb3V0Y29tZV9jb3JyZWxhdGlvbi5wZGYiKQoKZm9yKGsgaW4gdW5pcXVlKGludGVyJFF1ZXN0aW9uKSkKewogIGdfdGVtcCA9IGdyYXBoX2Zyb21fZGF0YV9mcmFtZShpbnRlcltpbnRlciRRdWVzdGlvbiA9PSBrLCBjKDUsNiwxOjQpXSwgZGlyZWN0ZWQgPSBGQUxTRSwgdmVydGljZXMgPSB0ZWFtcykKICBFKGdfdGVtcCkkd2VpZ2h0ID0gMQogIGdfdGVtcF9zaW1wID0gc2ltcGxpZnkoZ190ZW1wLCByZW1vdmUubG9vcHMgPSBGQUxTRSkKICAKICBzdGF0cyA9IGRhdGEuZnJhbWUoKQoKICBmb3IgKGkgaW4gVihnX3RlbXBfc2ltcCkkbmFtZSkKICB7CiAgICBpZiAoIWkgJWluJSAiT3JnYW5pemluZyBUZWFtIikKICAgIHsKICAgICAgaW50cmEgPSBFKGdfdGVtcF9zaW1wKSR3ZWlnaHRbZ2V0LmVkZ2UuaWRzKGdfdGVtcF9zaW1wLCB2cCA9IGMoaSwgaSkpXQogICAgICBvcmcgPSBFKGdfdGVtcF9zaW1wKSR3ZWlnaHRbZ2V0LmVkZ2UuaWRzKGdfdGVtcF9zaW1wLCB2cCA9IGMoaSwgIk9yZ2FuaXppbmcgVGVhbSIpKV0KICAgICAgdG90YWwgPSBzdHJlbmd0aChnX3RlbXBfc2ltcCwgdmlkcyA9IGkpCiAgICAgIAogICAgICBpZiAobGVuZ3RoKGludHJhKSA9PSAwKSAKICAgICAgICBpbnRyYSA9IDAKICAgICAgaWYobGVuZ3RoKG9yZykgPT0gMCkKICAgICAgICBvcmcgPSAwCiAgICAKICAgICAgc3RhdHMgPSByYmluZChzdGF0cywgZGF0YS5mcmFtZShUZWFtID0gaSwgc3RyZW5ndGhfaW50cmFfdGVhbSA9IGludHJhLCBzdHJlbmd0aF9vcmdfdGVhbSA9IG9yZywgc3RyZW5ndGhfaW50ZXJfdGVhbSA9ICh0b3RhbCAtICgyKmludHJhKSAtIG9yZyksIHN0cmVuZ3RoX2ludHJhX3RlYW1fbm9ybSA9IDIqaW50cmEvdG90YWwsIHN0cmVuZ3RoX29yZ190ZWFtX25vcm0gPSBvcmcvdG90YWwsIHN0cmVuZ3RoX2ludGVyX3RlYW1fbm9ybSA9ICh0b3RhbCAtICgyKmludHJhKSAtIG9yZykvdG90YWwpKQogICAgfQogIH0KICAKICB0ZW1wID0gbWVyZ2Uoc3RhdHMsIG91dGNvbWUsIGJ5LnggPSAiVGVhbSIsIGJ5LnkgPSAiVGVhbSIsIGFsbC54ID0gVFJVRSwgYWxsLnkgPSBUUlVFKQoKICBkZl9jb3JyID0gZGF0YS5mcmFtZSgpCiAgCiAgZm9yIChpIGluIGNvbG5hbWVzKG91dGNvbWUpKQogIHsKICAgIGlmKCEgaSAlaW4lIGMoIlRlYW0iLCAiU3RhZ2UiKSkKICAgIHsKICAgICAgZm9yIChqIGluIGNvbG5hbWVzKHN0YXRzKSkKICAgICAgewogICAgICAgIGlmKCFqICVpbiUgYygiVGVhbSIpKQogICAgICAgIHsKICAgICAgICAgIGMgPSBjb3IudGVzdCh0ZW1wWyxqXSwgdGVtcFssaV0pCiAgICAgICAgICAKICAgICAgICAgIGRmX2NvcnIgPSByYmluZChkZl9jb3JyLCBkYXRhLmZyYW1lKGkgPSBpLCBqID0gaiwgY29yID0gYyRlc3RpbWF0ZSwgcF92YWwgPSBjJHAudmFsdWUpKQogICAgICAgICAgCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIAogIGRmX2NvcnIkY29yW2RmX2NvcnIkcF92YWwgPiAwLjFdID0gMAogIGRmX2NvcnIkY29yID0gcm91bmQoZGZfY29yciRjb3IsIDMpCiAgCiAgcGx0ID0gZ2dwbG90KGRmX2NvcnIpICsgZ2VvbV90aWxlKGFlcyh4ID0gaSwgeSA9IGosIGZpbGwgPSBjb3IpLCBsd2QgPSAxLjUsIGxpbmV0eXBlID0gMSkgKyBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsIGhpZ2ggPSAicmVkIikgKyB0aGVtZV9idygpICsgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkgKyB5bGFiKCIiKSArIHhsYWIoIiIpICsgZ2VvbV90ZXh0KGFlcyh4ID0gaSwgeSA9IGosIGxhYmVsID0gY29yKSkgKyBnZ3RpdGxlKGspCiAgCiAgcHJpbnQocGx0KQp9CgpkZXYub2ZmKCkKCmBgYAoKClN0YWdlcyBDcm9zc2VkIHZzIFByb3BlcnRpZXMgKEV2YWx1YXRlKQoKYGBge3J9CgppbnRlcmFjdGlvbl9zdGF0cyA9IG1lcmdlKGludGVyYWN0aW9uX3N0YXRzLCB0ZWFtcywgYnkueCA9ICJUZWFtIiwgYnkueSA9ICJUZWFtIE5hbWUiLCBhbGwueCA9IFRSVUUpCgpwZGYoIi4uL2ZpZ3VyZXMvc3RhZ2VfcHJvcHMucGRmIikKCmZvciAoaSBpbiBjb2xuYW1lcyhpbnRlcmFjdGlvbl9zdGF0cykpCnsKICBpZiAoISBpICVpbiUgYygiVGVhbSIsICJTdGFnZSIsICdUeXBlJykpCiAgewogICAgdGVtcCA9IGludGVyYWN0aW9uX3N0YXRzWywgYygiU3RhZ2UiLCBpKV0KICAgIGNvbG5hbWVzKHRlbXApID0gYygiU3RhZ2UiLCAidmFyIikKICAgIAogICAgcGx0ID0gZ2dwbG90KHRlbXAsIGFlcyh4ID0gU3RhZ2UsIHkgPSB2YXIpKSArIGdlb21fcG9pbnQoYWVzKHggPSBTdGFnZSwgeSA9IHZhciksIGFscGhhID0gMC4zKSArIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDI1KSArIGdlb21fYm94cGxvdCgpICsgZ2d0aXRsZShpKSArIHlsYWIoIiIpCiAgICBwcmludChwbHQpCiAgfQp9CgpkZXYub2ZmKCkKCmBgYAoK